package com.yy.common.adapter;

import android.animation.Animator;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;

import com.yy.common.adapter.Constant.AnimationType;
import com.yy.common.adapter.animation.AlphaAnimation;
import com.yy.common.adapter.animation.BaseAnimation;
import com.yy.common.adapter.animation.ScaleAnimation;
import com.yy.common.adapter.animation.SlideInBottomAnimation;
import com.yy.common.adapter.animation.SlideInLeftAnimation;
import com.yy.common.adapter.animation.SlideInRightAnimation;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

/**
 * User: gongyongfeng2@yy.com
 * Date: 2020/4/25 20 :15
 */
public abstract class BaseAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static final String TAG = "BaseAdapter";
    private Context mContext;
    private int mLayoutResId;
    private List<T> mDataList;
    private OnItemClickListener mItemClickListener;

    private @AnimationType
    int animalType = Constant.ALPHA;
    private BaseAnimation mAnimation;
    private boolean isOpenAnimation = false;
    private boolean isFirstOnly = true;
    private int mDuration = 300;
    private Interpolator mInterpolator = new LinearInterpolator();
    private int mLastPosition = -1;
    private BaseAnimation mCustomAnimation = new AlphaAnimation();

    private ArrayList<View> mHeaderViews = new ArrayList<>();
    private ArrayList<View> mFootViews = new ArrayList<>();

    private static final int LOADING_VIEW = 1;
    private static final int HEADER_VIEW = 2;
    private static final int FOOTER_VIEW = 3;
    private boolean mNextLoad;
    private boolean mIsLoadingMore;

    private RequestLoadMoreListener mLoadMoreListener;

    public BaseAdapter(Context context, int layoutResId) {
        this(context, layoutResId, null);
    }

    public BaseAdapter(Context context, int layoutResId, List<T> list) {
        this.mContext = context;
        this.mLayoutResId = layoutResId;
        this.mDataList = list == null ? new ArrayList<T>() : list;
    }

    public void remove(int position) {
        mDataList.remove(position);
        notifyItemChanged(position);
    }

    public void add(int position, T item) {
        mDataList.add(position, item);
        notifyItemChanged(position);
    }

    @Override
    public int getItemCount() {
        int i = mNextLoad ? 1 : 0;
        return mDataList.size() + i + getHeaderViewsCount() + getFooterViewsCount();
    }

    @Override
    public int getItemViewType(int position) {
        if (position < getHeaderViewsCount()) {
            return HEADER_VIEW;
        } else if (position == mDataList.size() + getHeaderViewsCount()) {
            if (mNextLoad) {
                return LOADING_VIEW;
            } else {
                return FOOTER_VIEW;
            }
        }

        return super.getItemViewType(position);
    }

    @NonNull
    @Override
    public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View item = null;
        if (viewType == LOADING_VIEW) {
            item = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.def_loading, parent, false);
            return new FooterViewHodler(item);
        } else if (viewType == HEADER_VIEW) {
            return new HeaderViewHolder(mHeaderViews.get(0));
        } else if (viewType == FOOTER_VIEW) {
            return new HeaderViewHolder(mFootViews.get(0));
        }
        item = LayoutInflater.from(mContext).inflate(mLayoutResId, parent, false);

        return new BaseViewHolder(mContext, item);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
        BaseViewHolder viewHolder = (BaseViewHolder) holder;
        int type = getItemViewType(position);

        if (type == 0) {
            int index = position - getHeaderViewsCount();
            convert(viewHolder, mDataList.get(position));
            doAnimation(position, holder);
            if (mItemClickListener != null) {
                holder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        mItemClickListener.onItemClick(view, position);
                    }
                });
            }
        } else if (type == LOADING_VIEW) {
            if (mNextLoad && mLoadMoreListener != null && !mIsLoadingMore) {
                mIsLoadingMore = true;
                mLoadMoreListener.loadMore();
                if (holder.itemView
                        .getLayoutParams() instanceof StaggeredGridLayoutManager.LayoutParams) {
                    StaggeredGridLayoutManager.LayoutParams params =
                            (StaggeredGridLayoutManager.LayoutParams) holder.itemView
                                    .getLayoutParams();
                    params.setFullSpan(true);
                }
            }
        }
    }

    public abstract void convert(BaseViewHolder holder, T item);

    public void setItemClickListener(OnItemClickListener itemClickListener) {
        mItemClickListener = itemClickListener;
    }

    public void setLoadMoreListener(RequestLoadMoreListener loadMoreListener) {
        mNextLoad = true;
        mLoadMoreListener = loadMoreListener;
    }

    public void openLoadAnimation(@AnimationType int type) {
        isOpenAnimation = true;
        mCustomAnimation = null;
        switch (animalType) {
            case Constant.ALPHA:
                mAnimation = new AlphaAnimation();
                break;
            case Constant.SCALE:
                mAnimation = new ScaleAnimation();
                break;
            case Constant.SLIDE_BOTTOM:
                mAnimation = new SlideInBottomAnimation();
                break;
            case Constant.SLIDE_LEFT:
                mAnimation = new SlideInLeftAnimation();
                break;
            case Constant.SLIDE_RIGHT:
                mAnimation = new SlideInRightAnimation();
                break;
        }
    }

    public void isNextLoad(boolean isNextLoad) {
        mNextLoad = isNextLoad;
        mIsLoadingMore = false;
        notifyDataSetChanged();
    }

    public void addHeaderView(View header) {
        if (header == null) {
            throw new IllegalArgumentException("header not be null");
        }
        if (mHeaderViews.size() == 0) {
            mHeaderViews.add(header);
        }
        notifyDataSetChanged();
    }

    public void addFooterView(View footer) {
        if (footer == null) {
            throw new IllegalArgumentException("header not be null");
        }
        mNextLoad = false;
        if (mFootViews.size() == 0) {
            mFootViews.add(footer);
        }
        notifyDataSetChanged();
    }

    public void openLoadAnimation() {
        isOpenAnimation = true;
    }

    public void setFirstOnly(boolean firstOnly) {
        isFirstOnly = firstOnly;
    }

    public List<T> getDataList() {
        return mDataList;
    }

    public int getHeaderViewsCount() {
        return mHeaderViews.size();
    }

    public int getFooterViewsCount() {
        return mFootViews.size();
    }

    private void doAnimation(int position, RecyclerView.ViewHolder holder) {
        if (isOpenAnimation) {
            if (!isFirstOnly || position > mLastPosition) {
                BaseAnimation animation;
                if (mCustomAnimation != null) {
                    animation = mCustomAnimation;

                } else {
                    animation = mAnimation;
                }

                for (Animator animator : animation.getAnimators(holder.itemView)) {
                    animator.setDuration(mDuration);
                    animator.setInterpolator(mInterpolator);
                    animator.start();
                }
                mLastPosition = position;
            }
        }
    }

    public interface RequestLoadMoreListener {
        void loadMore();
    }

    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    }

    private class FooterViewHodler extends BaseViewHolder {

        public FooterViewHodler(@NonNull View itemView) {
            super(itemView.getContext(), itemView);
        }
    }

    private class HeaderViewHolder extends BaseViewHolder {

        public HeaderViewHolder(@NonNull View itemView) {
            super(itemView.getContext(), itemView);
        }
    }

}

